package my.dao;

import my.support.VoIODealer;
import my.vo.Vo;

import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * @author 星环
 * @date 2022/11/13 9:32:59
 * @description
 */
public abstract class CommonDao<T extends Vo> {

    protected List<T> list;

    protected VoIODealer<T> ioDealer;

    protected int idCounter;


    protected CommonDao(T tArchetype) {
        init(tArchetype);
    }

    private void init(T ta) {
        //idCounter和tInstance
        idCounter = 0;
        list = new LinkedList<>();
        String path = ta.getClass().getSimpleName() + "s";
        path = path.toLowerCase(Locale.ROOT);
        ioDealer = new VoIODealer<>(path);
        ioDealer.read(list, ta);
        idCounter = getNewIdCount();
    }

    /**
     * 返回新的id
     * @return
     */
    protected int getNewId(){
        return ++idCounter;
    }

    protected int getNewIdCount(){
        int max = -1;
        int total = 0;
            for (T t : list) {
                max = Math.max(t.getId(),max);
                total++;
            }
        return Math.max(max,total);
    }

    public void addNewVo(T vo){
        vo.setId(getNewId());
        Vo clone = vo.clone();
        list.add((T) clone);
    }

    public List<T> deleteBy(Predicate<T> p){
        List<T> tList = list.stream().filter(p).toList();
        list.removeIf(p);
        return viewOf(tList);
    }

    public List<T> updateBy(Predicate<T> p, Consumer<T> c){
        List<T> tList = list.stream().filter(p).toList();
        tList.forEach(c);
        return viewOf(tList);
    }

    public List<T> srchBy(Predicate<T> p) {
        List<T> tList = list.stream().filter(p).toList();
        return viewOf(tList);
    }

    private boolean checkIfNeedUpdate(Object newData) {
        if(newData == null){
            return false;
        }
        if(Integer.class.equals(newData.getClass())){
            return (Integer) newData < 0;
        }
        return true;
    }

    protected List<T> viewOf(List<T> tList){
        List<T> view = new LinkedList<>();
        tList.forEach(e->view.add((T)e.clone()));
        return view;
    }

    public void save(){
        ioDealer.save(list);
    }
}
